local function ontarget(inst, data)
    local self = inst.components.kkd_joinkill
    local target = data.target

    if not target:IsValid() then
        return
    end

    --add listener for the first time
    if not self.targets[target] then 
        inst:ListenForEvent("death", self.ontargetdeath, target)
        inst:ListenForEvent("onremove", self.ontargetremoved, target)
    end

    --refresh time
    self.targets[target] = GetTime()

end

---@class components
---@field kkd_joinkill component_kkd_joinkill

---@class component_kkd_joinkill
local joinkill = Class(function(self, inst)
    self.inst = inst 
    self.time = 10
    self.targets = {}
    inst:DoTaskInTime(0,function(inst)
        self.ontargetdeath = function(target) self:TargetDeath(target) end
        self.ontargetremoved = function(target) self:TargetRemoved(target) end
        inst:ListenForEvent("onattackother", ontarget)
        inst:ListenForEvent("onareaattackother", ontarget)
    end)
end)

function joinkill:SetTargetTime(time)
    self.time = time 
end

function joinkill:SetTargetDeathFn(name, fn)
    if not self.ontargetdeathfns then self.ontargetdeathfns = {} end
    self.ontargetdeathfns[name] = fn 
end

function joinkill:RemoveTargetDeathFn(name)
    if self.ontargetdeathfns then 
        self.ontargetdeathfns[name] = nil 
    end
end

function joinkill:SetTargetRemovedFn(name, fn)
    if not self.ontargetremovedfns then self.ontargetremovedfns = {} end
    self.ontargetremovedfns[name] = fn 
end

function joinkill:RemoveTargetRemovedFn(name)
    if self.ontargetremovedfns then 
        self.ontargetremovedfns[name] = nil 
    end
end

function joinkill:TargetDeath(target)
    if not self.targets[target] then return end

    local time = self.targets[target]
    if time and time + self.time >= GetTime() then
        if self.ontargetdeathfns then 
            for _, fn in pairs(self.ontargetdeathfns) do 
                fn(self.inst, target)
            end
        end
    end
    self:TargetRemoved(target)
end

function joinkill:TargetRemoved(target)
    if self.targets[target] then
        if self.ontargetremovedfns then
            for _, fn in pairs(self.ontargetremovedfns) do 
                fn(self.inst, target)
            end
        end
        self.targets[target] = nil
        
        self.inst:RemoveEventCallback("death", self.ontargetdeath, target)
        self.inst:RemoveEventCallback("onremove", self.ontargetremoved, target)
    end
end

--[[function joinkill:OnSave()
    local targets = {}
    for tar, time in pairs(self.targets) do 
        if time + self.time >= GetTime() then 
            targets[tar] = GetTime() - time
        end
    end
    return {
        time = self.time,
        targets = targets,
    }
end

function joinkill:OnLoad(data)
    self.time = data.time 
    for tar, time in pairs(data.targets) do
        ontarget(self.inst, {target = tar})
        self.targets[tar] = GetTime() - time
    end
end]]


return joinkill